/** 支持标签输入 */
import { deepCopy } from '@/utils'
import { validEmail } from '@/utils/validate'
import './style.scss'
// 内置验证器
const validatorList = {
  email: function(v) {
    return validEmail(v)
  }
}
function noNone(v) {
  return v !== '' && v !== undefined && v !== null
}
export default {
  name: 'TagInput',
  props: {
    value: {
      type: Array,
      default: () => []
    },
    type: {
      type: String,
      default: 'text'
    },
    validator: {
      type: [Function, String],
      default: undefined
    },
    placeholder: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      tags: [],
      error: false
    }
  },
  watch: {
    value: {
      handler(v) {
        this.tags = deepCopy(v || [])
      },
      immediate: true
    }
  },
  computed: {
    valueValidator() {
      const h = validatorList[this.validator]
      return h || noNone
    },
    hasTag() {
      return this.tags.length > 0
    }
  },
  render(h) {
    const tagNodeList = []
    for (let i = 0; i < this.tags.length; i++) {
      const tag = this.tags[i]
      tagNodeList.push(h('el-tag', {
        props: {
          closable: true,
          type: 'info'
        },
        key: i,
        on: {
          close: () => {
            this.tags.splice(i, 1)
            this.updateValue()
          }
        }
      }, tag))
    }
    const inputNode = h('input', {
      class: 'tag-input',
      style: {
        color: this.error ? '#ff4949' : '#606266'
      },
      attrs: {
        placeholder: this.hasTag ? '' : this.placeholder,
        type: this.type,
        autocomplete: 'off'
      },
      on: {
        keydown: e => {
          const keyCode = e.keyCode
          if (keyCode !== 13 && keyCode !== 8) return
          const value = (e.target.value || '').trim()
          if (keyCode === 13 && noNone(value)) {
            if (this.valueValidator(value)) {
              e.target.value = ''
              this.tags.push(value)
              this.updateValue()
            } else {
              this.error = true
            }
          } else if (keyCode === 8 && !noNone(value)) {
            this.error = false
            this.tags.pop()
            this.updateValue()
          }
        },
        input: e => {
          this.error = false
        },
        blur: e => {
          const value = e.target.value
          if (!noNone(value)) return
          if (this.valueValidator(value)) {
            e.target.value = ''
            this.tags.push(value)
            this.updateValue()
          } else {
            this.error = true
          }
        }
      }
    })
    const wrap = h('div', {
      class: 'wrapTags',
      style: {
        borderColor: this.error ? '#ff4949' : '#dcdfe6'
      }
    }, [tagNodeList, inputNode])
    const icon = h('span', {
      class: 'icon'
    }, [h('i', { class: 'el-icon-circle-close', on: {
      click: e => {
        this.tags = []
        inputNode.elm.value = ''
      }
    }})])
    return h('div', { class: ['container', this.hasTag ? 'container-icon' : ''] }, [wrap, icon])
  },
  methods: {
    updateValue() {
      this.$emit('input', deepCopy(this.tags))
    }
  }
}
